"""
Huber 损失函数
"""
import numpy as np
from keras.losses import Huber, huber


def get_data():
    """

    :return:
    """
    y_true = [[0.0, 1.0], [0.0, 0.0]]
    y_pred = [[0.6, 0.4], [0.4, 0.6]]
    return np.array(y_true), np.array(y_pred)


def compute_huber(y_true, y_pred, delta):
    """

    :param y_true:
    :param y_pred:
    :param delta:
    :return:
    """
    def mse(num):
        """

        :param num:
        :return:
        """
        return 0.5 * np.power(num, 2)

    def gt_delta(num):
        """

        :param num:
        :return:
        """
        return 0.5 * np.power(delta, 2) + delta * (num - delta)

    err = np.abs(y_true - y_pred)
    err = err.flatten()

    huber_arr = [mse(num) if num <= delta else gt_delta(num) for num in err]
    return np.mean(huber_arr)


def run():
    """
    主程序
    :return:
    """
    delta = 0.5
    y_true, y_pred = get_data()

    # 自己算
    my_loss = compute_huber(y_true=y_true, y_pred=y_pred, delta=delta)

    h = Huber(delta=delta)

    info = 'my: {}; Class: {}; Function: {}'.\
        format(my_loss, h(y_true=y_true, y_pred=y_pred),
               huber(y_true=y_true, y_pred=y_pred, delta=delta).numpy().mean())
    print(info)


if __name__ == '__main__':
    run()
